home *** CD-ROM | disk | FTP | other *** search
- #include "xdefs.h"
-
- #define TIMER_VECT 0x08
-
- #define PIC_CMD 0x20
- #define NONSPEC_EOI 0x20
- #define TIMER_MODE 0x34
- #define TIMER_CONTROL 0x43
- #define TIMER_0 0x40
-
- #define LATCH_COUNT 0x00
-
- #define INT_IN_ADVANCE 0x100
-
- #define DOS_GETVECT 0x3500
- #define DOS_SETVECT 0x2500
-
- WORD _TicksPerSecond;
- unsigned long _VsyncIntTicks;
- WORD _VsyncPeriod;
-
- WORD ClockRate;
- WORD ClockCounter;
- void ( __interrupt __far *UserVsyncHandler )();
- WORD InUserHandler;
-
- void * LocalStack;
-
- WORD ElapsedVrts;
- WORD VrtsToSkip = 1;
-
- inline void WaitVsyncStart(
- void
- )
- {
- while( inp( INPUT_STATUS_0 ) & 0x08 );
- while( !( inp( INPUT_STATUS_0 ) & 0x08 ) );
- }
-
-
- int get_vsync_period(
- void
- )
- {
- outp( TIMER_CONTROL, TIMER_MODE );
- outp( TIMER_0, 0 );
- outp( TIMER_0, 0 );
- //now wait for the vertical sync
- WaitVsyncStart();
- outp( TIMER_CONTROL, LATCH_COUNT );
- int iBegin = inp( TIMER_0 );
- iBegin += ( inp( TIMER_0 ) << 8 );
- //now iBegin = 65536 - clicks, so wait for the vsync again
- WaitVsyncStart();
- outp( TIMER_CONTROL, LATCH_COUNT );
- int iEnd = inp( TIMER_0 );
- iEnd += ( inp( TIMER_0 ) << 8 );
- //now iEnd = 65536 - clicks
- //now return iBegin - iEnd to get the change in clicks
- return( iBegin - iEnd );
- }
-
-
- void __interrupt __far vsync_int(
- void
- )
- {
- ++VsyncIntTicks;
- ++ElapsedVrts;
- //if there's something to do, do it.
- if ( ElapsedVrts >= VrtsToSkip ) {
- if ( StartAddressFlag != 0 ) {
- outpw( CRTC_INDEX, WaitingStartLow );
- outpw( CRTC_INDEX, WaitingStartHigh );
- }
- }
- //now stop the clock so we can re-sync
- _disable();
- outp( TIMER_CONTROL, TIMER_MODE );
- outp( TIMER_0, 255 );
- outp( TIMER_0, 255 );
- //now wait for the vsync again...
- while( inp( INPUT_STATUS_0 ) & 0x08 );
- //now restart yon clock...
- outp( TIMER_CONTROL, TIMER_MODE );
- outp( TIMER_0, ClockRate & 0xff );
- outp( TIMER_0, ClockRate >> 8 );
- //more checks on "if there's something to do..."
- if ( ElapsedVrts >= VrtsToSkip ) {
- if ( StartAddressFlag != 0 ) {
- ElapsedVrts = 0;
- outp( AC_INDEX, WaitingPelPan & 0xff );
- outp( AC_INDEX, WaitingPelPan >> 8 );
- StartAddressFlag = 0;
- }
- }
- //check for a palette update
- if ( VsyncPaletteCount != 0 ) {
- outp( DAC_WRITE_INDEX, VsyncPaletteStart & 0xff );
- BYTE * pbDacData = VsyncPaletteBuffer + VsyncPaletteStart;
- for ( int i = 0; i < VsyncPaletteCount; ++i ) {
- outp( DAC_DATA, *pbDacData++ );
- outp( DAC_DATA, *pbDacData++ );
- outp( DAC_DATA, *pbDacData++ );
- }
- VsyncPaletteCount = 0;
- }
- //check for a mouse update
- if ( MouseRefreshFlag != 0 ) {
- MouseVsyncHandler();
- }
- //check for a user vsync handler
- if ( UserVsyncHandler != NULL ) {
- if ( InUserHandler == 0 ) {
- SetStack(...)
- _enable();
- UserVsyncHandler();
- _disable();
- InUserHandler = 0;
- }
- }
- //now simulate the 18.2 Hz timer handler
- ClockCounter += VsyncPeriod;
- if ( ClockCounter >= 65536 ) {
- _enable();
- OldTimerInt();
- ClockCounter -= 65536;
- }
- outp( PIC_CMD, NONSPEC_EOI );
- _enable();
- }
-
-
- void x_install_vsync_handler(
- int iVrtSkipCount
- )
- {
- if ( iVrtSkipCount <= 0 ) {
- iVrtSkipCount = 0;
- }
- VrtsToSkip = iVrtSkipCount;
- ElapsedVrts = 0;
- if ( VsyncHandlerActive == TRUE ) {
- return;
- }
- int iPeriod = get_vsync_period;
- VsyncPeriod = iPeriod;
- iPeriod -= INT_IN_ADVANCE;
- ClockRate = iPeriod;
-
- TicksPerSecond = 13352 / VsyncPeriod;
- _disable();
- OldTimerInt = dos_getvect( TIMER_VECT );
- VsyncHandlerActive = TRUE;
- dos_setvect( TIMER_VECT, vsync_int );
- outp( TIMER_CONTROL, TIMER_MODE );
- outp( TIMER_0, ClockRate & 0xff );
- outp( TIMER_0, ClockRate >> 8 );
- }
-
- void x_remove_vsync_handler(
- void
- )
- {
- if ( VsyncHandlerActive == FALSE ) {
- return;
- }
- _disable();
- dos_setvect( TIMER_VECT, OldTimerInt );
- outp( TIMER_CONTROL, TIMER_MODE );
- outp( TIMER_0, 0 );
- outp( TIMER_0, 0 );
- _enable();
- }
-
- void x_set_user_vsync_handler(
- void ( __interrupt __far *pvHandlerProc )()
- )
- {
- _disable();
- UserVsyncHandler = pvHandlerProc;
- _enable();
- }
-